home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 22
/
Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso
/
Aminet
/
util
/
blank
/
BeyondTheDark.lha
/
BeyondTheDark
/
Developer
/
Source
/
Flame
/
Flame.c
next >
Wrap
C/C++ Source or Header
|
1995-04-05
|
9KB
|
354 lines
/* Flame Library */
#include <exec/memory.h>
#include <exec/execbase.h>
#include <graphics/gfxbase.h>
#include <intuition/intuitionbase.h>
#include <libraries/iffparse.h>
#include <utility/tagitem.h>
#include <clib/macros.h>
#define __USE_SYSBASE 42
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <math.h>
#include <btd.h>
// #define DEBUG YES
#ifdef DEBUG
void KPrintF(char *,...);
#define DEBUG_PRINTF(a,b) KPrintF(a,b);
#define DEBUG_PRINT(a) KPrintF(a)
#else
#define DEBUG_PRINTF(a,b)
#define DEBUG_PRINT(a)
#endif
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *UtilityBase,*MathIeeeDoubBasBase,*MathIeeeDoubTransBase;
#define FlameTAG(o) (BTD_Client+(o))
#define Flame_Colors FlameTAG(0)
#define Flame_Level FlameTAG(1)
#define MAX_COLORS 255L /* seconds until a new graphic is plotted */
#define DEF_COLORS 20L
#define MAX_LEVEL 10L
#define DEF_LEVEL 4L
struct BTDInteger FlameIntParams[] =
{
Flame_Colors,"Colors",BTDPT_INTEGER,DEF_COLORS,1L,MAX_COLORS,TRUE,
Flame_Level,"Patternchange",BTDPT_INTEGER,DEF_LEVEL,1L,MAX_LEVEL,TRUE
};
struct BTDNode *FlameParams[] = {
&FlameIntParams[0].BI_Node,
&FlameIntParams[1].BI_Node,
NULL
};
struct BTDInfo FlameInfo =
{
BTDI_Revision,MAKE_ID('F','L','A','M'),
"Flame","based on Flame\nScientific American","Markus Illenseer",
FlameParams
};
#define MAXTOTAL 10000
#define MAXBATCH 10
#define MAXLEV 4
struct XPoint
{
int x,y;
};
struct FlameStruct
{
struct BTDDrawInfo *BTDDrawInfo;
LONG hs_RandN,hs_RandF,hs_RandI;
double f[2][3][MAXLEV];/* three non-homogeneous transforms */
int max_levels;
int cur_level;
int snum;
int anum;
int width, height;
int num_points;
int total_points;
int pixcol;
int numcol;
int alt;
struct XPoint pts[MAXBATCH];
};
/* library stuff */
char MyBlankerName[] = "flame.btd";
char MyBlankerID[] = "Flame Blanker V" VERSION "." REVISION " for BTD";
LONG MyBlankerLibInit(void)
{
if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
{
if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
{
if (UtilityBase=OpenLibrary("utility.library",37L))
{
if (MathIeeeDoubBasBase=OpenLibrary("mathieeedoubbas.library",37L))
{
if (MathIeeeDoubTransBase=OpenLibrary("mathieeedoubtrans.library",37L)) return TRUE;
CloseLibrary (MathIeeeDoubBasBase);
}
CloseLibrary (UtilityBase);
}
CloseLibrary (&IntuitionBase->LibNode);
}
CloseLibrary (&GfxBase->LibNode);
}
return FALSE;
}
void MyBlankerLibFree(void)
{
CloseLibrary (MathIeeeDoubTransBase);
CloseLibrary (MathIeeeDoubBasBase);
CloseLibrary (UtilityBase);
CloseLibrary (&IntuitionBase->LibNode);
CloseLibrary (&GfxBase->LibNode);
}
/* random generator */
void __regargs InitRandom(struct FlameStruct *FlameStruct,ULONG Instance)
{
ULONG Time[2];
CurrentTime (&Time[0],&Time[1]);
FlameStruct->hs_RandN=(LONG)Time[0];
if (Time[1]<1024L) Time[1]|=1;
else Time[1]>>=10;
Time[1]^=Instance;
FlameStruct->hs_RandF=4*Time[1]+1;
FlameStruct->hs_RandI=2*Time[1]+1;
}
WORD __regargs Random(struct FlameStruct *FlameStruct,WORD Max)
{
FlameStruct->hs_RandN=FlameStruct->hs_RandF*FlameStruct->hs_RandN+FlameStruct->hs_RandI;
if (FlameStruct->hs_RandN<0L) FlameStruct->hs_RandN=-FlameStruct->hs_RandN;
return (WORD)(FlameStruct->hs_RandN%Max);
}
/* implementation of library functions */
struct BTDInfo *QueryMyBlanker(void)
{
return &FlameInfo;
}
#define NUM_RAINBOW_COLORS 6
UBYTE RBRed[NUM_RAINBOW_COLORS+1] = {0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF};
UBYTE RBGreen[NUM_RAINBOW_COLORS+1] = {0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00};
UBYTE RBBlue[NUM_RAINBOW_COLORS+1] = {0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00};
struct FlameStruct *InitMyBlanker(struct TagItem *TagList)
{
struct BTDDrawInfo *BTDDrawInfo;
struct FlameStruct *FlameStruct;
ULONG *Error,Dummy,Instance;
int Index;
if ((BTDDrawInfo=(struct BTDDrawInfo *)
GetTagData(BTD_DrawInfo,NULL,TagList))==NULL) return NULL;
Error=(ULONG *)GetTagData(BTD_Error,(ULONG)&Dummy,TagList);
if ((FlameStruct=AllocVec(2*sizeof(struct FlameStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
{
*Error=BTDERR_Memory;
return NULL;
}
Instance=GetTagData(BTD_Instance,0L,TagList);
FlameStruct->BTDDrawInfo=BTDDrawInfo;
FlameStruct->numcol=GetTagData(Flame_Colors,DEF_COLORS,TagList);
FlameStruct->max_levels=GetTagData(Flame_Level,DEF_LEVEL,TagList);
InitRandom (FlameStruct,Instance);
FlameStruct->width = BTDDrawInfo->BDI_Width-1;
FlameStruct->height = BTDDrawInfo->BDI_Height-1;
FlameStruct->cur_level = 0;
FlameStruct->alt = 0;
FlameStruct->anum = 0;
FlameStruct->snum = 0;
if (FlameStruct->numcol>NUM_RAINBOW_COLORS)
{
LONG ColNum,Col,RBCol;
UBYTE *Red,*Green,*Blue,*Changed;
Red=BTDDrawInfo->BDI_Red;
Green=BTDDrawInfo->BDI_Green;
Blue=BTDDrawInfo->BDI_Blue;
Changed=BTDDrawInfo->BDI_Changed;
ColNum=FlameStruct->numcol/NUM_RAINBOW_COLORS+1L;
Index=0L;
for (RBCol=0L; RBCol<NUM_RAINBOW_COLORS; RBCol++)
{
if (RBCol==(FlameStruct->numcol%NUM_RAINBOW_COLORS)) ColNum--;
for (Col=0L; Col<ColNum; Col++)
{
Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[RBCol]+((RBRed[RBCol+1]-RBRed[RBCol])*Col)/ColNum;
Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[RBCol]+((RBGreen[RBCol+1]-RBGreen[RBCol])*Col)/ColNum;
Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[RBCol]+((RBBlue[RBCol+1]-RBBlue[RBCol])*Col)/ColNum;
Changed[BTDDrawInfo->BDI_Pens[Index++]]=TRUE;
}
}
}
else
for (Index=0L; Index<FlameStruct->numcol; Index++)
{
BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[Index];
BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[Index];
BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[Index];
BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
}
FlameStruct->pixcol=1;
SetAPen(FlameStruct->BTDDrawInfo->BDI_RPort,BTDDrawInfo->BDI_Pens[FlameStruct->pixcol]);
return FlameStruct;
}
void XDrawPoints(struct FlameStruct *fs)
{
LONG Index;
int x,y;
DEBUG_PRINT("Flame: Drawing Points\n");
for(Index=0; Index<fs->num_points; Index++)
{
x=fs->pts[Index].x;
y=fs->pts[Index].y;
if(x<fs->width && x>0 && y<fs->height && y>0)
WritePixel(fs->BTDDrawInfo->BDI_RPort, x, y);
}
}
static BOOL recurse(struct FlameStruct *fs, double x, double y, int l)
{
int /*xp, yp,*/ i;
double nx, ny;
if (l == fs->max_levels) {
fs->total_points++;
if (fs->total_points > MAXTOTAL) /* how long each fractal runs */
return FALSE;
if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) {
/* xp = */ fs->pts[fs->num_points].x = (int) ((fs->width / 2)
* (x + 1.0));
/* yp = */ fs->pts[fs->num_points].y = (int) ((fs->height / 2)
* (y + 1.0));
fs->num_points++;
if (fs->num_points > MAXBATCH) { /* point buffer size */
XDrawPoints(fs);
fs->num_points = 0;
}
}
} else {
for (i = 0; i < fs->snum; i++) {
nx = fs->f[0][0][i] * x + fs->f[0][1][i] * y + fs->f[0][2][i];
ny = fs->f[1][0][i] * x + fs->f[1][1][i] * y + fs->f[1][2][i];
if (i < fs->anum) {
nx = sin(nx);
ny = sin(ny);
}
if (!recurse(fs, nx, ny, l + 1))
return FALSE;
}
}
return TRUE;
}
void EndMyBlanker(struct FlameStruct *FlameStruct)
{
DEBUG_PRINT("Flame: End\n");
FreeVec (FlameStruct);
}
void AnimMyBlanker(struct FlameStruct *fs)
{
int i, j, k;
DEBUG_PRINT("Flame: Anim\n");
if (!(fs->cur_level++ % fs->max_levels)) {
SetRast(fs->BTDDrawInfo->BDI_RPort,0);
fs->alt = !fs->alt;
} else {
SetAPen(fs->BTDDrawInfo->BDI_RPort, fs->BTDDrawInfo->BDI_Pens[fs->pixcol]);
if (--fs->pixcol < 1)
fs->pixcol = fs->numcol;
}
/* number of functions */
fs->snum = 2 + (fs->cur_level % (MAXLEV - 1));
/* how many of them are of alternate form */
if (fs->alt)
fs->anum = 0;
else
fs->anum = Random(fs,fs->snum) + 2;
/* 6 coefs per function */
for (k = 0; k < fs->snum; k++) {
for (i = 0; i < 2; i++)
for (j = 0; j < 3; j++)
fs->f[i][j][k] = ((double) Random(fs,fs->width) / (fs->width/2.0) - 1.0);
}
fs->num_points = 0;
fs->total_points = 0;
(void) recurse(fs, 0.0, 0.0, 0);
XDrawPoints(fs);
}
ULONG PenCountMyBlanker(struct TagItem *TagList)
{
return GetTagData(Flame_Colors,DEF_COLORS,TagList);
}